﻿namespace IS.Projecto.ImportarCSV
{
    using System;
    using System.Collections;
    using System.Collections.Generic;
    using System.IO;
    using System.Linq;
    using System.Text;
    using Modelo;

    public class CsvDirectoryImporter
    {
        #region Fields

        private readonly string _csvSource;
        private int _numeradorInscricoes;
        private int _numeradorDocentes;
        private int _numeradorHorarios;
        private ArrayList _horarioFiles;
        private ArrayList _inscricoesFiles;
        private readonly IList<Curso> _listaCursos;
        private readonly IList<Docente> _listaDocentes;
        private readonly IList<Horario> _listaHorarios;
        private readonly IList<Inscricao> _listaInscricoes;
        private readonly IList<Sala> _listaSalas;
        private readonly IList<UnidadeCurricular> _listaUCs;

        #endregion

        #region Properties

        public IList<Curso> ListaCursos
        {
            get { return _listaCursos; }
        }
        public IList<Docente> ListaDocentes
        {
            get { return _listaDocentes; }
        }
        public IList<Horario> ListaHorarios
        {
            get { return _listaHorarios; }
        }
        public IList<Inscricao> ListaInscricoes
        {
            get { return _listaInscricoes; }
        }
        public IList<Sala> ListaSalas
        {
            get { return _listaSalas; }
        }
        public IList<UnidadeCurricular> ListaUCs
        {
            get { return _listaUCs; }
        }

        #endregion

        #region Constructors

        public CsvDirectoryImporter(string csvSource)
        {
            _csvSource = csvSource;

            _listaCursos = new List<Curso>();
            _listaDocentes = new List<Docente>();
            _listaHorarios = new List<Horario>();
            _listaInscricoes = new List<Inscricao>();
            _listaSalas = new List<Sala>();
            _listaUCs = new List<UnidadeCurricular>();
        }

        #endregion

        #region Members

        public void Import()
        {
            //Inicializa os dados
            _numeradorInscricoes = 1;
            _numeradorDocentes = 1;
            _numeradorHorarios = 1;

            _listaCursos.Clear();
            _listaDocentes.Clear();
            _listaHorarios.Clear();
            _listaInscricoes.Clear();
            _listaSalas.Clear();

            //Carrega os ficheiros csv da pasta de dados
            SearchCsvFiles();

            //Vamos fazer a importação dos ficheiros de Inscrições
            AnalyzeInscriptionFiles();

            //Vamos fazer a importação dos ficheiros de Horários
            AnalyzeSchedulleFiles();
        }

        private void AnalyzeInscriptionFiles()
        {
            foreach (string file in _inscricoesFiles)
            {
                Console.WriteLine("Analizar ficheiro de Inscrições {0}", file);
                string line = "";
                Stream fileStream = null;

                try
                {
                    fileStream = new FileStream(file, FileMode.Open);
                    var reader = new StreamReader(fileStream, Encoding.UTF7);

                    //ignora a linha do cabeçalho
                    reader.ReadLine();

                    while (!reader.EndOfStream)
                    {
                        line = reader.ReadLine();
                        var curso = CsvParser.GetCurso(line);
                        if (!_listaCursos.Contains(curso))
                            _listaCursos.Add(curso);

                        var uc = CsvParser.GetUnidadeCurricular(line);
                        if (!_listaUCs.Contains(uc))
                            _listaUCs.Add(uc);

                        var inscricao = CsvParser.GetInscricao(line);
                        inscricao.Id = _numeradorInscricoes++;
                        _listaInscricoes.Add(inscricao);
                    }
                }
                catch (Exception error)
                {
                    Console.WriteLine("Error na linha {0}\n{1}", line, error.Message);
                }
                finally
                {
                    if (fileStream != null)
                        fileStream.Close();
                }
            }
        }

        private void AnalyzeSchedulleFiles()
        {
            foreach (string file in _horarioFiles)
            {
                Console.WriteLine("Analizar ficheiro de Horários {0}", file);
                string line = "";
                Stream fileStream = null;

                try
                {
                    fileStream = new FileStream(file, FileMode.Open);
                    var reader = new StreamReader(fileStream, Encoding.UTF7);

                    //ignora a linha do cabeçalho
                    reader.ReadLine();

                    while (!reader.EndOfStream)
                    {
                        line = reader.ReadLine();
                        var docente = CsvParser.GetDocente(line);
                        if (!_listaDocentes.Contains(docente))
                        {
                            docente.Id = _numeradorDocentes++;
                            _listaDocentes.Add(docente);
                        }

                        var sala = CsvParser.GetSala(line);
                        if (!_listaSalas.Contains(sala))
                            _listaSalas.Add(sala);

                        var uc = CsvParser.GetUnidadeCurricular(line);
                        var ucs = from p in _listaUCs
                                  where p.Id == uc.Id
                                  select p;

                        foreach (var item in ucs)
                        {
                            item.Nome = uc.Nome;
                        }

                        var horario = CsvParser.GetHorario(line, _listaDocentes);
                        horario.Id = _numeradorHorarios++;
                        _listaHorarios.Add(horario);
                    }
                }
                catch (Exception error)
                {
                    Console.WriteLine("Error na linha {0}\n{1}", line, error.Message);
                }
                finally
                {
                    if (fileStream != null)
                        fileStream.Close();
                }
            }
        }

        private void SearchCsvFiles()
        {
            _horarioFiles = new ArrayList();
            _inscricoesFiles = new ArrayList();
            var files = Directory.GetFiles(_csvSource, "*.csv");

            //classifica os ficheiros consoante são dados de horários ou de inscrições
            foreach (string s in files)
            {
                Stream fileStream = null;
                try
                {
                    fileStream = new FileStream(s, FileMode.Open);
                    var reader = new StreamReader(fileStream);
                    string line = reader.ReadLine();
                    if (line.ToLower().Equals("origem;cd_curso;cd_aluno;cd_discip"))
                    {
                        _inscricoesFiles.Add(s);
                    }
                    else if (
                        line.ToLower().Equals(
                            "id_uc;ds_discip;id_turno;data_aula;hora_inicio;hora_fim;id_sala;sala;docente"))
                    {
                        _horarioFiles.Add(s);
                    }
                }
                catch (Exception error)
                {
                    Console.WriteLine(error.Message);
                }
                finally
                {
                    if (fileStream != null)
                        fileStream.Close();
                }
            }
        }

        #endregion
    }
}